
import 'dart:convert';

import 'package:deepseek_client/common/network/GeminiClient.dart';
import 'package:dio/dio.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:retrofit/retrofit.dart';

import '../../common/network/DioUtils.dart';
import '../../common/network/OllamaClient.dart';

class AiModel{
  final String name;
  bool? selected = false;

  AiModel(this.name , {this.selected});
}

abstract class IChatService {

  Future<List<AiModel>> findModels();

  Future<Object?> chatStream(Map request , CancelToken? token);
}


class OllamaChatService implements IChatService {
  OllamaClient? client;

  OllamaChatService(){
    client = OllamaClient(DioUtils.getInstance().dio!);
  }

  @override
  Future<List<AiModel>> findModels() async{
    var local = await client?.getLocalModels();
    var localModels = local?.models ?? [];
    List<AiModel> results = [];
    for (var model in localModels) {
      results.add(AiModel(model.name ?? ""));
    }
    return results;
  }

  @override
  Future<HttpResponse<dynamic>?> chatStream(Map request , CancelToken? cancelToken) async{
    var httpResponse = await client?.chatWithStream(cancelToken!, json.encode(request));
    return httpResponse;
  }
}


class GeminiChatService implements IChatService {
  GeminiClient? client;
  
  GeminiChatService(){
    client = GeminiClient(DioUtils.getInstance().dio!);
  }
  
  @override
  Future<List<AiModel>> findModels() async{
    String apiKey = dotenv.env['GEMINI_KEY'] ?? "";
    var localResult = await client?.getLocalModels(apiKey);
    var localModels = localResult?.models ?? [];
    List<AiModel> results = [];
    for (var model in localModels) {
      results.add(AiModel(model.name ?? ""));
    }
    return results;
  }

  @override
  Future<Object?> chatStream(Map<dynamic, dynamic> model, CancelToken? token) async{
    return null;
  }


}

class VolcEngineService implements IChatService {
  @override
  Future<List<AiModel>> findModels() async{
    return [];
  }

  @override
  Future<Object?> chatStream(Map<dynamic, dynamic> model, CancelToken? token) async{
    return null;
  }


}